package com.hsy.crm.web.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.StoreProduct;
import com.hsy.crm.web.domain.entity.TransferOrder;
import com.hsy.crm.web.domain.entity.TransferOrderDetail;
import com.hsy.crm.web.domain.ex.ServiceException;
import com.hsy.crm.web.domain.po.transferOrder.TransferDetailPo;
import com.hsy.crm.web.domain.po.transferOrder.TransferGetPo;
import com.hsy.crm.web.domain.po.transferOrder.TransferOrderPagePo;
import com.hsy.crm.web.domain.vo.transfer.TransferVo;
import com.hsy.crm.web.domain.vo.transferOrder.TransferOrderPageVo;
import com.hsy.crm.web.mapper.TransferOrderDetailMapper;
import com.hsy.crm.web.mapper.TransferOrderMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.CacheService;
import com.hsy.crm.web.service.base.DataInitService;
import com.hsy.crm.web.utils.CalcUtils;
import com.hsy.crm.web.utils.ServiceUtils;
import com.hsy.crm.web.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class TransferOrderService extends BaseService<TransferOrder> {

    @Autowired
    TransferOrderMapper transferOrderMapper;

    @Autowired
    TransferOrderDetailMapper transferOrderDetailMapper;

    @Autowired
    MessageService messageService;

    @Autowired
    StoreProductService storeProductService;

    @Transactional
    public Unified<TransferOrder> insertTransferOrder(TransferVo vo) {
        Unified<TransferOrder> unified = new Unified<>();
        // order
        TransferOrder order = vo.getOrder();
        order.setLoginCompanyId(vo.getLoginCompanyId());
        order.setCustomerId(vo.getCustomerId());
        order.setCode(DataInitService.getOrderCode());
        order.setLoginUserId(vo.getLoginUserId());
        order.setStatus(App.Status.BC);
        this.insert(order);
        vo.setOrder(order);
        //order details
        this.insertDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            this.examine(vo);
        }

        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<TransferOrder> updateTransferOrder(TransferVo vo) {
        TransferOrder order = vo.getOrder();
        order.setLoginUserId(vo.getLoginUserId());
        order.setCustomerId(vo.getCustomerId());
        this.update(order);

        //order details
        this.deleteDetails(order);
        this.insertDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            this.examine(vo);
        }

        Unified<TransferOrder> unified = new Unified<>();
        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<Integer> deleteTransferOrder(TransferOrder transferOrder) {
        this.deleteDetails(transferOrder);
        return Unified.newInstance(this.delete(transferOrder));
    }

    @Transactional
    public Unified<Integer> examine(TransferVo orderVo){
        TransferOrder order = orderVo.getOrder();
        order.setLoginCompanyId(orderVo.getLoginCompanyId());
        order.setCompanyId(order.getLoginCompanyId());

        this.updateStatus(order,App.Status.SH);

        List<TransferOrderDetail> orderDetails = orderVo.getDetails();
        this.update_store_product_exam(orderVo);
        messageService.addMessage(order,orderDetails,App.ExamType.EXAMINE);
        return Unified.newInstance();
    }

    @Transactional
    public Unified<Integer> doInvalid(TransferOrder order){
        Unified<Integer> unified = new Unified<>();
        this.updateStatus(order,App.Status.BC);
        order.setCompanyId(order.getLoginCompanyId());

        List<TransferOrderDetail> orderDetails = getOrderDetails(order);
        this.update_store_product_invalid(orderDetails,order.getCustomerId(),order.getCompanyId());

        messageService.addMessage(order,orderDetails,App.ExamType.INVALID);
        return unified;
    }

    public Unified<TransferGetPo> getOrder(TransferOrder transferOrder) {
        Unified<TransferGetPo> unified = new Unified<>();

        TransferOrder order = transferOrderMapper.selectByPrimaryKey(transferOrder);
        List<TransferDetailPo> details = transferOrderMapper.findOrderDetails(transferOrder);

        TransferGetPo po = new TransferGetPo();
        po.setOrder(order);
        po.setDetails(details);
        unified.setData(po);

        return unified;
    }

    public PageResult<TransferOrderPagePo> page(TransferOrderPageVo transferOrderPageVo) {
        Page page = PageHelper.startPage(transferOrderPageVo.getPage(),transferOrderPageVo.getLimit());
        PageResult<TransferOrderPagePo> pageResult = new PageResult<>();
        pageResult.setRows(transferOrderMapper.page(transferOrderPageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    private List<TransferOrderDetail> getOrderDetails(TransferOrder order){
        TransferOrderDetail orderDetail = new TransferOrderDetail();
        orderDetail.setTransferOrderId(order.getId());
        orderDetail.setCustomerId(order.getCustomerId());
        return transferOrderDetailMapper.select(orderDetail);
    }

    private void update_store_product_exam(TransferVo transferVo){
        for( TransferOrderDetail detail : transferVo.getDetails() ){

            StoreProduct storeProduct = getStoreProduct(transferVo.getCustomerId(),transferVo.getOrder().getCompanyId(),detail);
            storeProduct.setPrice(getPrice(detail,detail.getOutPrice()));
            storeProduct.setStoreId(detail.getOutStoreId());
            storeProductService.update(storeProduct,App.StoreType.OUT);
            detail.setOutStoreProductId(storeProduct.getId());

            storeProduct = getStoreProduct(transferVo.getCustomerId(),transferVo.getOrder().getCompanyId(),detail);
            storeProduct.setPrice(getPrice(detail,detail.getInPrice()));
            storeProduct.setStoreId(detail.getInStoreId());
            storeProductService.update(storeProduct,App.StoreType.IN);
            detail.setInStoreProductId(storeProduct.getId());

        }
    }

    private void update_store_product_invalid(List<TransferOrderDetail> orderDetails,String customerId,Long companyId){
        for( TransferOrderDetail detail : orderDetails ){

            StoreProduct storeProduct = getStoreProduct(customerId,companyId,detail);
            storeProduct.setPrice(getPrice(detail,detail.getOutPrice()));
            storeProduct.setStoreId(detail.getOutStoreId());
            storeProductService.update(storeProduct,App.StoreType.IN);

            storeProduct = getStoreProduct(customerId,companyId,detail);
            storeProduct.setPrice(getPrice(detail,detail.getInPrice()));
            storeProduct.setStoreId(detail.getInStoreId());
            storeProductService.update(storeProduct,App.StoreType.OUT);
        }
    }

    public static Long getPrice(TransferOrderDetail orderDetail,Long price){
        double totalPrice = CalcUtils.mul(orderDetail.getNumber(),price);
        totalPrice = CalcUtils.div(totalPrice,App.DECIMAL.DIV);
        return ((Double)totalPrice).longValue();
    }

    private static StoreProduct getStoreProduct(String customerId,Long companyId,TransferOrderDetail orderDetail){
        StoreProduct storeProduct = new StoreProduct();
        storeProduct.setCompanyId(companyId);
        storeProduct.setProductId(orderDetail.getProductId());
        //storeProduct.setStoreId(orderDetail.getStoreId());
        storeProduct.setUnitId(orderDetail.getUnitId());
        storeProduct.setCustomerId(customerId);
        storeProduct.setNumber(orderDetail.getNumber());

        return storeProduct;
    }

    private void deleteDetails(TransferOrder transferOrder){
        TransferOrderDetail detail = new TransferOrderDetail();
        detail.setCustomerId(transferOrder.getCustomerId());
        detail.setTransferOrderId(transferOrder.getId());
        transferOrderDetailMapper.delete(detail);
    }

    private void insertDetails(TransferVo vo){
        for(TransferOrderDetail detail : vo.getDetails()){
            if( !CacheService.hasProductId(vo.getCustomerId(),detail.getProductId()) ){
                throw new ServiceException(detail.getProductId());
            }
            detail.setTransferOrderId(vo.getOrder().getId());
            detail.setCustomerId(vo.getCustomerId());
            detail.setId(UuidUtils.getUuid());

            ServiceUtils.init_entity_insert(detail);
            transferOrderDetailMapper.insert(detail);
        }
    }

    private void updateStatus(TransferOrder transferOrder,Integer status){
        TransferOrder order = new TransferOrder();
        order.setStatus(status);
        order.setId(transferOrder.getId());
        order.setCustomerId(transferOrder.getCustomerId());
        transferOrderMapper.updateByPrimaryKeySelective(order);
    }

}
